﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Graphics.PackedVector;

namespace RainEngine.Helper 
{
    // XNA Framework无法处理只包含位置信息的顶点，
    // 你当然可以使用一个复杂结构，比如VertexPositionColor而将颜色数据保持为空值，但这样做仍会将颜色数据发送到显卡，会浪费带宽。
    // 要使程序保持清晰，你可以创建最简单的顶点格式，只包含位置数据。VertexPosition结构定义了一个自定义的顶点格式，只包含一个Vector3存储位置信息。
    public struct VertexPosition:IVertexType 
    {
        public Vector3 Position;
        
        public VertexPosition(Vector3 position)
        {
            this.Position = position;
        }

        public readonly static VertexDeclaration VertexDeclaration = new VertexDeclaration
            (
            new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0)
            );

        VertexDeclaration IVertexType.VertexDeclaration
        {
            get { return VertexDeclaration; }
        }
    }
    
    // 高级地形使用的自定义顶点格式，储存了顶点位置、法线和纹理坐标，还有每个顶点的4个权重
    public struct VertexMultitextured : IVertexType
    {
        public Vector3 Position;
        public Vector3 Normal;
        public Vector2 TextureCoordinate;
        public Vector4 TexWeights;

        public readonly static VertexDeclaration VertexDeclaration = new VertexDeclaration
            (
            new VertexElement( 0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0 ),
            new VertexElement( sizeof(float) * 3, VertexElementFormat.Vector3, VertexElementUsage.Normal, 0 ), 
            new VertexElement( sizeof(float) * 6, VertexElementFormat.Vector2,VertexElementUsage.TextureCoordinate, 0 ),            
              new VertexElement( sizeof(float) * 8, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 1)
            );

        VertexDeclaration IVertexType.VertexDeclaration
        {
            get { return VertexDeclaration; }
        }
        
        
    }

    public struct VertexPositionTextureNormalTangentBinormal : IVertexType
    {
        public Vector3 Position;
        public Vector2 TextureCoordinate;
        public Vector3 Normal;        
        public Vector3 Tanget;
        public Vector3 Binormal;

        public readonly static VertexDeclaration VertexDeclaration = new VertexDeclaration
            (
            new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
            new VertexElement(12, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0),
            new VertexElement(20, VertexElementFormat.Vector3, VertexElementUsage.Normal, 0),            
            new VertexElement(32, VertexElementFormat.Vector3, VertexElementUsage.Tangent, 0),
            new VertexElement(44, VertexElementFormat.Vector3, VertexElementUsage.Binormal, 0)
            );

        VertexDeclaration IVertexType.VertexDeclaration
        {
            get { return VertexDeclaration; }
        }
    }

    /// <summary>
    /// 绘制3D粒子的自定义顶点结构。
    /// </summary>
    struct ParticleVertex : IVertexType
    {
        // Stores which corner of the particle quad this vertex represents.
        public Short2 Corner;
        // Stores the starting position of the particle.
        public Vector3 Position;
        // Stores the starting velocity of the particle.
        public Vector3 Velocity;
        // Four random values, used to make each particle look slightly different.
        public Color Random;
        // The time (in seconds) at which this particle was created.
        public float Time;

        // Describe the layout of this vertex structure.
        public static readonly VertexDeclaration VertexDeclaration = new VertexDeclaration
            (
            new VertexElement(0, VertexElementFormat.Short2,VertexElementUsage.Position, 0),
            new VertexElement(4, VertexElementFormat.Vector3,VertexElementUsage.Position, 1),
            new VertexElement(16, VertexElementFormat.Vector3,VertexElementUsage.Normal, 0),
            new VertexElement(28, VertexElementFormat.Color,VertexElementUsage.Color, 0),
            new VertexElement(32, VertexElementFormat.Single,VertexElementUsage.TextureCoordinate, 0)
            );

        VertexDeclaration IVertexType.VertexDeclaration
        {
            get { return VertexDeclaration; }
        }
        // Describe the size of this vertex structure.
        public const int SizeInBytes = 36;
    }
}